package com.light.generator.util;


import com.light.common.utils.DateUtils;
import com.light.common.utils.SuperStringUtils;
import com.light.generator.domain.GeneratorInfo;
import com.light.generator.domain.TableDO;
import com.light.generator.exception.GeneratorException;
import com.light.generator.handler.GeneratorHandler;
import org.apache.commons.io.IOUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 代码生成器 工具类
 */

/**
 *
 * @ClassName:  GenUtils
 * @Description:TODO
 * @author:
 * @date:   2019年1月15日 下午2:53:06
 * @version: v1.0
*
 */
public class GenUtils {

	public static List<String> getTemplates() {
		List<String> templates = new ArrayList<String>();
		templates.add("generator/domain.java.vm");
		templates.add("generator/Mapper.java.vm");
		templates.add("generator/Mapper.xml.vm");
		templates.add("generator/Service.java.vm");
		templates.add("generator/ServiceImpl.java.vm");
		templates.add("generator/Controller.java.vm");
		templates.add("generator/Query.java.vm");

		/// templates.add("templates/common/generator/menu.sql.vm");
		return templates;
	}

	/**
	 * 生成代码
	 */

	public static void generatorCode(GeneratorInfo generatorInfo, Map<String, String> table, List<Map<String, String>> columns,
									 ZipOutputStream zip) {
		TableDO tableDO = new GeneratorHandler(table,columns).handle(generatorInfo.getTablePrefix());

		// 设置velocity资源加载器
		Properties prop = new Properties();
		prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
		Velocity.init(prop);
		// 封装模板数据
		Map<String, Object> map = new HashMap<>(16);
		map.put("tableName", tableDO.getTableName());
		map.put("comments", tableDO.getComments());
		map.put("pk", tableDO.getPk());
		map.put("className", tableDO.getClassName());
		map.put("classNameLowerCase", tableDO.getClassNameLowerCase());
		map.put("pathName", subStringPathName(generatorInfo));
		map.put("columns", tableDO.getColumns());
		map.put("comments", tableDO.getColumns().get(1).getComments());
	    map.put("columnsName", tableDO.getColumns().get(1).getColumnName());
		map.put("package", generatorInfo.getPackages());
		map.put("author", generatorInfo.getAuthor());
		map.put("email", generatorInfo.getEmail());
		map.put("datetime", DateUtils.format(new Date(), DateUtils.DATE_PATTERN));
		VelocityContext context = new VelocityContext(map);
		// 获取模板列表
		List<String> templates = getTemplates();
		for (String template : templates) {
			// 渲染模板
			StringWriter sw = new StringWriter();
			Template tpl = Velocity.getTemplate(template, "UTF-8");
			tpl.merge(context, sw);

			try {
				// 添加到zip
				zip.putNextEntry(new ZipEntry(getFileName(template, tableDO.getClassNameLowerCase(), tableDO.getClassName(),
						subStringPathName(generatorInfo))));
				IOUtils.write(sw.toString(), zip, "UTF-8");
				IOUtils.closeQuietly(sw);
				zip.closeEntry();
			} catch (IOException e) {
				throw new GeneratorException("渲染模板失败，表名：" + tableDO.getTableName());
			}
		}
	}

	private static String subStringPathName(GeneratorInfo generatorInfo) {
		return generatorInfo.getPackages().substring(generatorInfo.getPackages().lastIndexOf(".") + 1);
	}

	/**
	 * 获取文件名
	 */
	public static String getFileName(String template, String classNameLowerCase, String className, String packageName) {
		String packagePath = "main" + File.separator + "java" + File.separator;
		String domainJavaVm="domain.java.vm";
		String daoJavaVm="Mapper.java.vm";
		String serviceJavaVm="Service.java.vm";
		String queryJavaVM="Query.java";
		String serviceImplJavaVm="ServiceImpl.java.vm";
		String controllerJavaVm="Controller.java.vm";
		String mapXmlVm="Mapper.xml.vm";
//		String listHtmlVm="list.html.vm";
//		String addHtmlVm="add.html.vm";
//		String editHtmlVm="edit.html.vm";
//		String listJsVm="list.js.vm";
//		String addJsVm="add.js.vm";
//		String editJsVm="edit.js.vm";
		/// String modulesname=config.getString("packageName");
		if (SuperStringUtils.isNotBlank(packageName)) {
			packagePath += packageName.replace(".", File.separator) + File.separator;
		}
		if (template.contains(domainJavaVm)) {
			return packagePath + "domain" + File.separator + className + "DO.java";
		}
		if (template.contains(daoJavaVm)) {
			return packagePath + "mapper" + File.separator + className + "Mapper.java";
		}
//		if(template.contains("Mapper.java.vm")){
//			return packagePath + "dao" + File.separator + className + "Mapper.java";
//		}
		if (template.contains(serviceJavaVm)) {
			return packagePath + "service" + File.separator + className + "Service.java";
		}
		if (template.contains(serviceImplJavaVm)) {
			return packagePath + "service" + File.separator + "impl" + File.separator + className + "ServiceImpl.java";
		}
		if (template.contains(controllerJavaVm)) {
			return packagePath + "controller" + File.separator + className + "Controller.java";
		}
		if (template.contains(queryJavaVM)) {
			return packagePath + "query" + File.separator + className + "Query.java";
		}
		if (template.contains(mapXmlVm)) {
			return "main" + File.separator + "resources" + File.separator + "mapper" + File.separator  + className + "Mapper.xml";
		}
//		if (template.contains(listHtmlVm)) {
//			return "main" + File.separator + "resources" + File.separator + "templates" + File.separator + packageName
//					+ File.separator + classNameLowerCase + File.separator + classNameLowerCase + ".html";
//			// + "modules" + File.separator + "generator" + File.separator +
//			// className.toLowerCase() + ".html";
//		}
//		if (template.contains(addHtmlVm)) {
//			return "main" + File.separator + "resources" + File.separator + "templates" + File.separator + packageName
//					+ File.separator + classNameLowerCase + File.separator + "add.html";
//		}
//		if (template.contains(editHtmlVm)) {
//			return "main" + File.separator + "resources" + File.separator + "templates" + File.separator + packageName
//					+ File.separator + classNameLowerCase + File.separator + "edit.html";
//		}
//		if (template.contains(listJsVm)) {
//			return "main" + File.separator + "resources" + File.separator + "static" + File.separator + "js"
//					+ File.separator + "appjs" + File.separator + packageName + File.separator + classNameLowerCase
//					+ File.separator + classNameLowerCase + ".js";
//			// + "modules" + File.separator + "generator" + File.separator +
//			// className.toLowerCase() + ".js";
//		}
//		if (template.contains(addJsVm)) {
//			return "main" + File.separator + "resources" + File.separator + "static" + File.separator + "js"
//					+ File.separator + "appjs" + File.separator + packageName + File.separator + classNameLowerCase
//					+ File.separator + "add.js";
//		}
//		if (template.contains(editJsVm)) {
//			return "main" + File.separator + "resources" + File.separator + "static" + File.separator + "js"
//					+ File.separator + "appjs" + File.separator + packageName + File.separator + classNameLowerCase
//					+ File.separator + "edit.js";
//		}
//		if(template.contains("menu.sql.vm")){
//			return className.toLowerCase() + "_menu.sql";
//		}
		return null;
	}


}
